package com.polaris.live.ui.party.fragment.game

import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.core.os.bundleOf
import com.bumptech.glide.Glide
import com.gyf.immersionbar.ImmersionBar
import com.lxj.xpopup.XPopup
import com.polaris.live.R.id.fragment_game
import com.polaris.live.cache.CommonCache
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.ext.dp
import com.polaris.live.common.ext.formatNumberWithK
import com.polaris.live.common.ext.setOnSingleClickListener
import com.polaris.live.common.network.parseState
import com.polaris.live.common.util.JsonUtils
import com.polaris.live.common.util.NavigationBarUtils
import com.polaris.live.common.util.ToastGravity
import com.polaris.live.common.util.ViewUtils
import com.polaris.live.constant.LiveConst
import com.polaris.live.constant.UserConst
import com.polaris.live.databinding.FragmentPartyGameAnchorBinding
import com.polaris.live.dialog.AwardProgressDialog
import com.polaris.live.dialog.GlobalDialogManager
import com.polaris.live.dialog.LiveHangUpDialog
import com.polaris.live.dialog_fragment.MusicPopup
import com.polaris.live.dialog_fragment.RoomInvitationFragmentDialog
import com.polaris.live.dialog_fragment.magiclamp.MagicLampPopup
import com.polaris.live.im.manager.ImLiveManager
import com.polaris.live.im.manager.RouterControlManager
import com.polaris.live.im.sfs.BIG_BROTHER_ENTERS_ROOM
import com.polaris.live.im.sfs.LIVE_MAGIC_LAMP_90
import com.polaris.live.im.sfs.LIVE_MAGIC_LAMP_OPEN
import com.polaris.live.im.sfs.LIVE_NEW_ANCHOR
import com.polaris.live.im.sfs.LIVE_PARTY_EMOJI
import com.polaris.live.im.sfs.LIVE_PUBLIC_SCREEN
import com.polaris.live.im.sfs.LIVE_SEND_GIFT
import com.polaris.live.im.sfs.LIVE_WARN_MESSAGE
import com.polaris.live.im.sfs.LUCKY_BACKPACK_GIFT
import com.polaris.live.im.sfs.bean.live.LivePublicScreenMessage
import com.polaris.live.im.sfs.bean.live.LiveRoomInfo
import com.polaris.live.im.sfs.bean.live.SendLiveCloseMessage
import com.polaris.live.im.sfs.bean.live.SendLiveFloatingMessage
import com.polaris.live.im.sfs.bean.live.SendLiveMessage
import com.polaris.live.im.sfs.bean.live.SendLiveNoticeMessage
import com.polaris.live.im.sfs.bean.live.ext.LiveEnterBean
import com.polaris.live.im.sfs.bean.live.ext.MessageUserExtBean
import com.polaris.live.im.sfs.bean.live.ext.UserBasicVo
import com.polaris.live.im.sfs.bean.live.payload.InviteGiftPayloadBean
import com.polaris.live.im.sfs.bean.live.payload.LiveNoticePayloadBean
import com.polaris.live.im.sfs.bean.live.payload.NewAnchorSubsidyPayloadBean
import com.polaris.live.im.sfs.core.bean.DataArgument
import com.polaris.live.im.utils.SmartFoxUtils.parseVariables
import com.polaris.live.manager.AppConfigManager
import com.polaris.live.popup.ContributionListPopup
import com.polaris.live.popup.GameListPopup
import com.polaris.live.popup.GlobalPopupManager
import com.polaris.live.popup.MagicLampWinRewardPopup
import com.polaris.live.popup.VipBarrageWhatPopup
import com.polaris.live.popup.party.InteractionEmojiPopup
import com.polaris.live.popup.party.RoomInfoAnchorPopup
import com.polaris.live.popup.party.RoomManagementPopup
import com.polaris.live.popup.party.SeatSettingPopup
import com.polaris.live.popup.party.UnLockSeatPopup
import com.polaris.live.resp.back_resp.InfoOtherResp
import com.polaris.live.resp.back_resp.LiveEmojiResp
import com.polaris.live.resp.back_resp.LiveStopReceiptResp
import com.polaris.live.resp.back_resp.LiveSubsidyIndicatorResp
import com.polaris.live.resp.back_resp.toUserBasicVo
import com.polaris.live.resp.bean.MagicLampCountDownBean
import com.polaris.live.translation.R
import com.polaris.live.ui.game.GameUtils
import com.polaris.live.ui.live.proxy.LivePublicProxy
import com.polaris.live.ui.live.proxy.gift.EntryScreenAnimationProxy
import com.polaris.live.ui.live.proxy.gift.GiftAnimationProxy
import com.polaris.live.ui.live.widget.listener.OnBackPressedListener
import com.polaris.live.ui.live.widget.listener.OnLiveNetworkListener
import com.polaris.live.ui.live.widget.listener.OnSendPartyMessageListener
import com.polaris.live.ui.message.fragment.MessageSessionFragment
import com.polaris.live.ui.message.fragment.dialog.MessageSessionDialogFragment
import com.polaris.live.ui.message.fragment.dialog.MessageSingleDialogFragment
import com.polaris.live.ui.party.PartyUserStateUtil
import com.polaris.live.ui.party.fragment.base.BasePartyFragment
import com.polaris.live.ui.party.listener.GamePlayListener
import com.polaris.live.ui.party.listener.OnRoomFinishCallback
import com.polaris.live.ui.party.listener.PartyImListener
import com.polaris.live.ui.party.utils.BigBrotherEntersTheArenaProxy
import com.polaris.live.ui.party.utils.GiftDialogProxy
import com.polaris.live.ui.party.utils.GiftGivingAnimationProxy
import com.polaris.live.ui.party.utils.PartyImProxy
import com.polaris.live.ui.party.widget.PartyBottomView
import com.polaris.live.ui.party.widget.seat.SeatBeanUtil
import com.polaris.live.ui.party.widget.seat.bean.SeatBean
import com.polaris.live.ui.party.widget.seat.listener.PartySeatListener
import com.polaris.live.utils.LiveUtils
import com.polaris.live.utils.StartLiveProxy
import com.polaris.live.utils.TaskRedListener
import com.polaris.live.utils.TaskRedProxy
import com.polaris.live.utils.XPopupUtils
import com.polaris.live.utils.file.FileUtils
import com.polaris.live.utils.fragment.attachFragment
import com.polaris.live.utils.fragment.showNewDialogFragment
import com.polaris.live.utils.image.ImageUtils
import com.polaris.live.utils.route.RoutePath
import com.polaris.live.utils.route.Router
import com.polaris.live.utils.zego.LiveEngineManage
import com.polaris.live.utils.zego.media.MediaProxy
import com.polaris.live.viewmodel.party.game.PartyGameAnchorFragmentModel
import sfs2x.client.core.SFSEvent
import sfs2x.client.entities.variables.RoomVariable
import java.io.File

/**
 * PartyGameAnchorFragment
 *
 * @author Created by 天晴 on 2024/3/13 9:50
 * @since 1.0.0
 */
class PartyGameAnchorFragment : BasePartyFragment<PartyGameAnchorFragmentModel, FragmentPartyGameAnchorBinding>(),
    OnLiveNetworkListener, OnBackPressedListener, GamePlayListener, GameUtils.GameStateListener {

    private val mLiveInfo by lazy {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            arguments?.getParcelable(LiveConst.Params.LIVE_INFO, LiveRoomInfo::class.java)
        } else {
            arguments?.getParcelable(LiveConst.Params.LIVE_INFO)
        } ?: throw IllegalArgumentException("liveInfo is null")
    }
    private val mSessionFragment by lazy {
        MessageSessionDialogFragment().apply {
            arguments = bundleOf(
                LiveConst.Params.NEED_CLICK_AVATAR to false
            )
        }
    }
    private var mGameMode: Boolean = false //是否在游戏模式
    private var mLiveIsClose: Boolean = false //直播间是否已关闭
    private var mLiveStopReceiptResp: LiveStopReceiptResp? = null //直播间关闭时的数据
    private var mSubsidy: LiveSubsidyIndicatorResp? = null

    private val mPartyImProxy by lazy {
        PartyImProxy.create(mLiveInfo.liveId, mLiveInfo.userId, mPartyImListener, this)
    }
    private var mPauseLiving: Boolean = false
    private var mStopLive: Boolean = false

    //被禁言的人
    private val mBanMessageUser = mutableListOf<Long>()

    //房管
    private val mAdministrators = mutableListOf<Long>()

    private var mEmojiList: List<LiveEmojiResp>? = null

    private var mGamePlayFragment: GamePlayFragment? = null
    private var mBaiShunGamePlayFragment: BaiShunGamePlayFragment? = null

    private var mRoomFinishCallback: OnRoomFinishCallback? = null

    private val mGiftGivingAnimationProxy by lazy {
        GiftGivingAnimationProxy(mViewModel, this)
    }

    private val mBigBrotherEntersTheArenaProxy by lazy {
        BigBrotherEntersTheArenaProxy(mBinding.gifta, this)
    }

    /**
     * 进场动效
     */
    private val mEntryScreenAnimationProxy by lazy {
        EntryScreenAnimationProxy(
            requireActivity(),
            mBinding.entryFloatingScreen,
            mBinding.entryScreen,
            viewLifecycleOwner
        )
    }
    private val mLivePublicProxy by lazy {
        LivePublicProxy(requireContext(), mViewModel)
    }

    //礼物代理
    private val mGiftProxy by lazy {
        GiftAnimationProxy(this, requireActivity(), mBinding.llGift, mLiveInfo.nickname).apply {
            //礼物队列点击头像
            setOnHeadOnClickListener {
                showPartyUserProfilePopup(it, true)
            }
        }
    }

    //礼物轮盘代理
    private val mGiftDialogProxy by lazy {
        GiftDialogProxy(requireContext(), mViewModel, mLiveInfo, mBinding.icRun, true)
            .apply {
                setOnUserProfileClickListener {//礼物轮盘点击查看礼物
                    showPartyUserProfilePopup(it, true)
                }
            }
    }

    private fun getGameIsPlaying(): Boolean {
        return when (mLiveInfo.gameProviderType) {
            1 -> {
                mBaiShunGamePlayFragment?.isGamePlaying() ?: false
            }

            2 -> {
                mGamePlayFragment?.isGamePlaying() ?: false
            }

            else -> {
                false
            }
        }
    }

    private fun updateLiveRoomInfo(name: String, liveInfo: LiveRoomInfo) {
        when (mLiveInfo.gameProviderType) {
            1 -> {
                mBaiShunGamePlayFragment?.updateLiveRoomInfo(name, liveInfo)
            }

            2 -> {
                mGamePlayFragment?.updateLiveRoomInfo(name, liveInfo)
            }
        }
    }

    /**
     * =============================Im消息回调===========================
     */
    private val mPartyImListener = object : PartyImListener {
        override fun closeRoomMessage(da: SendLiveCloseMessage) {
            onStopLive()
        }

        override fun variableUpdate(variable: RoomVariable) {
            val liveInfo = mLiveInfo
            LiveUtils.fillLiveInfo(liveInfo, variable)
            SeatBeanUtil.getSeatId(variable.name)?.let {
                mBinding.partySeat.setUpdateDateSeat(it, liveInfo)
            }
            updateLiveRoomInfo(variable.name, liveInfo)
            when (variable.name) {
                "showGainCoins" -> {
                    mBinding.contributionView.showGainCoins((liveInfo.showGainCoins?.formatNumberWithK()) ?: "0")
                }

                "banMessageUser" -> {
                    upDataBanMessage(liveInfo)
                }

                "administrator" -> {
                    upDataAdministrator(liveInfo)
                }
                "roomTheme" -> {
                    setSkinUi()
                }
            }
        }

        override fun userCountChange(count: Int) {
        }

        override fun publicMessage(sendLiveMessage: SendLiveMessage) {
            if (sendLiveMessage.type in ImLiveManager.publicTypes && sendLiveMessage.businessId == mLiveInfo.liveId) {
                mBinding.vMessage.addMessage(sendLiveMessage)
                if (sendLiveMessage.type == LIVE_PUBLIC_SCREEN) {
                    val ext = sendLiveMessage.ext as? MessageUserExtBean
                    val isGameMode = mGameMode
                    val isUserMessage = ext?.user?.userId == UserManager.getUserId()
                    if (ext?.type == 1) {
                        if (!isGameMode || isUserMessage) {
                            mBinding.barrageView.addMessage(sendLiveMessage)
                        }
                    }
                }
            }

            //其他消息处理
            when (sendLiveMessage.type) {
                LIVE_SEND_GIFT, LUCKY_BACKPACK_GIFT -> {
                    val ext = sendLiveMessage.ext as MessageUserExtBean
                    val payload = sendLiveMessage.payload as InviteGiftPayloadBean

                    if (!getGameIsPlaying()) {
                        mGiftGivingAnimationProxy.sendGiftEffect(
                            requireContext(),
                            sendLiveMessage,
                            mBinding.partySeat.getSeatData()
                        )
                        mGiftProxy.addAnimation(sendLiveMessage)
                        payload.gift.animation?.let { mBinding.widgetGift.setGift(payload) }
                    }

                    val isWinning = payload.reward != null && payload.reward.times > 0
                    if (isWinning && UserManager.getUserId() == ext.user.userId) {
                        if (sendLiveMessage.type != LUCKY_BACKPACK_GIFT) {
                            GlobalDialogManager.showUserWinning(requireContext(), payload)
                        } else {
                            GlobalDialogManager.showBackPackUserWinning(requireContext(), payload)
                        }
                    }
                }
                //警告消息
                LIVE_WARN_MESSAGE -> {
                    mLivePublicProxy.onPublicMessage(sendLiveMessage)
                }
                //emoji消息
                LIVE_PARTY_EMOJI -> {
                    mBinding.partySeat.showUserEmoji(sendLiveMessage)
                }
                //新主播补贴消息
                LIVE_NEW_ANCHOR -> {
                    val payload = sendLiveMessage.payload as NewAnchorSubsidyPayloadBean
                    GlobalDialogManager.showNewLiveAnchor(requireContext(), payload)
                }
                //大哥进场
                BIG_BROTHER_ENTERS_ROOM -> {
                    mBigBrotherEntersTheArenaProxy.addData(sendLiveMessage)
                }
                //神灯进度90%
                LIVE_MAGIC_LAMP_90 -> {
                    mBinding.widgetRoomBanner.upDataMagicLamp()
                }
                //神灯开奖
                LIVE_MAGIC_LAMP_OPEN -> {
                    val payload = sendLiveMessage.payload as MagicLampCountDownBean
                    mBinding.widgetRoomBanner.upDataMagicLamp()
                    mBinding.widgetMagicLamp.addMagicLampPag(payload)
                }
            }
        }

        override fun liveEvent(command: String, argument: DataArgument) {
            when (command) {
                SFSEvent.USER_ENTER_ROOM -> {
                    val user = argument.getUser()
                    if (user == null || user.name == UserManager.getUserId().toString()) {
                        return
                    }
                    argument.getUser()?.parseVariables<LiveEnterBean>()?.let {
                        mEntryScreenAnimationProxy.addEntryScreenOtherUser(it) {
                            mBinding.vEnter.addEnterBean(it)
                        }
                    }
                }

                SFSEvent.USER_EXIT_ROOM -> {
                    val user = argument.getUser()
                    if (user == null || user.name == UserManager.getUserId().toString()) {
                        return
                    }
                    mEntryScreenAnimationProxy.removeEntryScreen(user.name.toLong())

                }
                //如果是加入则刷新直播间的信息
                SFSEvent.ROOM_JOIN -> {
                    argument.getRoom()?.also { room ->
                        room.variables.forEach {
                            variableUpdate(it)
                        }
                    }
                }
            }
        }

        override fun floatingMessage(message: SendLiveFloatingMessage) {
            mBinding.widgetFloat.addFloatView(message)
        }

        override fun noticeMessage(message: SendLiveNoticeMessage) {
            super.noticeMessage(message)
            val payload = message.payload ?: return
            val fromJson = JsonUtils.fromJson<LiveNoticePayloadBean>(payload)
            //如果是pag 就判断是否下载过了
            if (fromJson?.titleImageType == LiveConst.NoticeImageType.PAG) {
                val path =
                    FileUtils.getFilePath(FileUtils.getPagFile(), message.titleImage)
                if (File(path).exists()) {
                    GlobalDialogManager.showLiveNotice(requireContext(), message)
                } else {
                    mViewModel.downLoadPag(message)
                }
            } else {
                GlobalDialogManager.showLiveNotice(requireContext(), message)
            }

        }
    }

    /**
     * 底部点击
     */
    private val mBottomBuilder by lazy {
        PartyBottomView.Builder()
            .setShowGameButton(!GameUtils.getLiveCacheGameList().isNullOrEmpty())
            .setShowMessageButton(true)
            .setShowSettingButton(true)
            .setShowSendrButton(true)
            .setShowGiftButton(true)
            .setSendrClickBack {
                mBinding.vEdit.showKeyboard()
            }
            .setEmojiClickBack {
                showInteractionEmojiPopup()
            }
            .setGameClickBack {
                showGameList()
            }
            .setMessageClickBack {
                showChatMessage()
            }
            .setSettingClickBack {
                showRoomManagementPopup()
            }
            .setMikeStateBack {
                mViewModel.siteMicSwitch(mLiveInfo.userId, it == 1)
            }
            .setGiftClickBack {
                mGiftDialogProxy.showGiftPopup(seatList = mBinding.partySeat.getSeatData())
            }
    }

    private fun initImmersionBar() {
        ImmersionBar.with(this)
            .transparentBar()
            .titleBarMarginTop(mBinding.vHeader)
            .init()

        NavigationBarUtils.setNavigationHeight(mBinding.bottom)
    }

    override fun initView(savedInstanceState: Bundle?) {
        initImmersionBar()
        GameUtils.addGameStateListener(this)
        initObserve()
        initListener()

        mGiftGivingAnimationProxy.initSeatViewAddr(
            mBinding.gifta, 0, 0, Pair("1", mBinding.partySeat.mBinding.seat1),
            Pair("2", mBinding.partySeat.mBinding.seat2),
            Pair("3", mBinding.partySeat.mBinding.seat3),
            Pair("4", mBinding.partySeat.mBinding.seat4),
            Pair("5", mBinding.partySeat.mBinding.seat5),
            Pair("6", mBinding.partySeat.mBinding.seat6),
            Pair("7", mBinding.partySeat.mBinding.seat7),
            Pair("8", mBinding.partySeat.mBinding.seat8),
        )

        mBinding.apply {
            vHeader.initData(pageType, mLiveInfo, 1)
            vMessage.initData(pageType, mLiveInfo)
            vEdit.initData(mLiveInfo)
            contributionView.showGainCoins(mLiveInfo.showGainCoins?.formatNumberWithK() ?: "0")
            CommonCache.getMagicLampList().forEach { widgetMagicLamp.addMagicLampPag(it) }
        }
        mBinding.bottom.initialize(mBottomBuilder, mViewModel)
        mBinding.partySeat.setInitJoinData(mLiveInfo, mLiveInfo.userId)
        mBinding.widgetRoomBanner.initBannerData(lifecycle, mViewModel, mLiveInfo.liveId, mLiveInfo.userId)

        mPartyImProxy

        initGameFragment()

        when (mLiveInfo.gameProviderType) {
            1 -> {
                mBaiShunGamePlayFragment
            }

            2 -> {
                mGamePlayFragment?.let {
                    LiveEngineManage.gameEventHandlerHelper.observe(this, it)
                }
            }

            else -> {
                mRoomFinishCallback?.onRoomFinishCallback()
                return
            }
        }


        Glide.with(this)
            .load(ImageUtils.imgPath(mLiveInfo.background))
            .placeholder(com.polaris.live.R.drawable.party_bg)
            .centerCrop()
            .into(mBinding.gameBg)
        upDataBanMessage(mLiveInfo)
        upDataAdministrator(mLiveInfo)
        mViewModel.getSubsidy()
        mViewModel.openClearTimeJob()
        mViewModel.getBackGiftRed()
        mBinding.actMarquee.getActivitiesScroll(mViewModel, mLiveInfo.userId)
        setSkinUi()
    }

    private fun initGameFragment() {
        when (mLiveInfo.gameProviderType) {
            1 -> {
                mBaiShunGamePlayFragment = childFragmentManager.attachFragment(fragment_game) {
                    BaiShunGamePlayFragment().apply {
                        arguments = bundleOf(
                            LiveConst.Params.IS_ANCHORID to true,
                            LiveConst.Params.LIVE_INFO to mLiveInfo
                        )
                    }
                }.apply {
                    setGamePlayListener(this@PartyGameAnchorFragment)
                }
            }

            2 -> {
                mGamePlayFragment = childFragmentManager.attachFragment(fragment_game) {
                    GamePlayFragment().apply {
                        arguments = bundleOf(
                            LiveConst.Params.IS_ANCHORID to true,
                            LiveConst.Params.LIVE_INFO to mLiveInfo
                        )
                    }
                }.apply {
                    setGamePlayListener(this@PartyGameAnchorFragment)
                }
            }
        }

    }

    override fun initData() {
        mViewModel.getGameList(mLiveInfo.liveId)

    }

    override fun onResume() {
        super.onResume()
        onLiveResume()
    }

    private fun onLiveResume() {
        mViewModel.launchConsumeUser(mLiveInfo.liveId) //定时5秒请求一次  顶部消费列表
        mPauseLiving = false
    }

    override fun onPause() {
        super.onPause()
        mPauseLiving = true
    }

    private fun initListener() {
        mBinding.apply {
            //直播间飘屏被点击
            widgetFloat.setOnSingleClickListener { data ->
                when (data.type) {
                    3L -> { //游戏中奖
                        GameUtils.showAndCheckGameFragment(
                            requireContext(),
                            mLiveInfo.userId,
                            data.payload
                        )
                    }
                }
            }
            //直播间用户列表
            vHeader.setOnConsumeItemClickListener { _, item ->
                showPartyUserProfilePopup(item.userId, true)
            }
            //点击主播头像
            vHeader.setOnAvatarClientListener {
                showRoomInfoPopup()
            }
            viewPage.setOnSingleClickListener {
                vMessage.closeMessage()
            }
            //显示头像
            vMessage.mBinding.baseMessage.setOnUserProfileClickListener {
                showPartyUserProfilePopup(it, true)
            }
            //点击在线人数
            vHeader.setOnOnlineClickListener {
                GlobalPopupManager.showOnRoomUser(
                    requireContext(), this@PartyGameAnchorFragment, mViewModel,
                    mLiveInfo.liveId, mLiveInfo.userId,
                    LiveConst.Type.PARTY_GAME_LIVE,
                    mAdministrators,
                    onHeadClickListener = { userId ->
                        showPartyUserProfilePopup(userId, true)
                    }, onSendGiftSomeOneCallback = { userBase ->
                        userBase ?: return@showOnRoomUser
                        if (userBase.userId != UserManager.getUserId()) {
                            showChatMessage(userBase)
                        }
                    }
                )
            }
            //公屏举报
            vMessage.mBinding.baseMessage.setOnReportListener {
                if (it.ext is MessageUserExtBean) {
                    GlobalPopupManager.showReport(
                        requireContext(), it.ext.user.nickname,
                        mViewModel, it.ext.user.userId, mLiveInfo.liveId
                    )
                }
            }
            vMessage.setOnClick {
                mBinding.vEdit.showKeyboard()
            }
            /**
             * 座位回调
             */
            partySeat.setPartySeatListener(object : PartySeatListener {
                /**
                 * 被点击
                 */
                override fun clickItem(index: Int, seatBean: SeatBean) {
                    //有人
                    if (seatBean.userBasicVo != null) {
                        seatBean.userBasicVo?.userId?.let {
                            showPartyUserProfilePopup(it, false, seatBean)
                        }
                    } else {
                        if (seatBean.siteLock == true) {
                            showUnLockSeatPopup(seatBean.seatId)
                        } else {
                            showSeatPopup(seatBean)
                        }

                    }
                }

                override fun updateOneSelfSeat(seatBean: SeatBean?) {
                    if (seatBean == null || seatBean.siteMicStatus != 1) {
                        MediaProxy.closeMusic()
                    }
                    mBinding.bottom.apply {
                        if (seatBean == null) {
                            showMikeButton(false)
                            showEmojiButton(false)
                        } else {
                            setMikeState(seatBean.siteMicStatus ?: 1)
                            showMikeButton(true)
                            showEmojiButton(true)
                        }
                    }
                }

                override fun soundLevelUpdate(seatId: Int, soundLevel: Float) {
                    mLiveInfo.let {
                        mViewModel.taskMicReport(it.liveId.toString(), seatId.toLong(), soundLevel.toString())
                    }

                }
            })
            /**
             * 点击贡献榜
             */
            contributionView.setOnSingleClickListener {
                ContributionListPopup.showPop(
                    requireContext(),
                    this@PartyGameAnchorFragment,
                    mViewModel,
                    UserManager.getUserId()
                ) {
                    mSessionFragment.show(
                        childFragmentManager,
                        MessageSessionDialogFragment.FRAGMENT_TAG
                    )
                    childFragmentManager.showNewDialogFragment(
                        MessageSingleDialogFragment(
                            it.user.userId,
                            it.user.avatar,
                            it.user.avatarFrame,
                            it.user.chatBubble,
                            false
                        ), MessageSessionFragment.FRAGMENT_TAG
                    )
                }
            }
            widgetRoomBanner.setMagicLampListener {
                mLiveInfo.let { info ->
                    MagicLampPopup.show(this@PartyGameAnchorFragment, mViewModel, info.userId, false) {
                        mGiftDialogProxy.showGiftPopup(seatList = mBinding.partySeat.getSeatData())
                    }
                }

            }
            barrageView.addReportCallBack {
                GlobalPopupManager.showReport(
                    requireContext(),
                    it.nickname,
                    mViewModel,
                    it.userId,
                    it.userId
                )
            }
        }

    }

    private fun initObserve() {
        mViewModel.clearTimeLiveData.observe(this) { _ ->
            mGiftGivingAnimationProxy.clearOverTimeQueue()
        }
        //发送公屏消息
        mBinding.vEdit.setOnSendPartyMessageListener(object : OnSendPartyMessageListener {
            override fun onSendPublicMessage(message: LivePublicScreenMessage) {
                mViewModel.sendPublicMessage(message)
            }

            override fun onBarrageWhat() {
                VipBarrageWhatPopup.showPop(requireContext(), true) {
                    Router.instance.setPath(RoutePath.VIP_CENTER_ACTIVITY)
                        .withInt("page", 0)
                        .withInt("level", 6)
                        .navigation(requireContext())
                }
            }
        })
        //关闭直播监听
        mViewModel.stopLiveLiveData.observe(this) { resultState ->
            parseState(resultState, {
                mLiveStopReceiptResp = it
            })
            if (!GameUtils.gameRun && !mGameMode) {
                mLiveStopReceiptResp?.let {
                    Router.builder(RoutePath.VOICE_END_ACTIVITY)
                        .withAny(LiveConst.Params.LIVE_END_INFO, it)
                        .withInt("liveType", LiveConst.Type.PARTY_GAME_LIVE)
                        .navigation(requireActivity())
                }
                mRoomFinishCallback?.onRoomFinishCallback()
            } else {
                mLiveIsClose = true
            }
        }
        //点击隐藏edit
        ViewUtils.registerTouchDown(mBinding.widgetGift) {
            mBinding.vEdit.hideKeyboard()
        }
        //获取emoji列表
        mViewModel.mEmojiListLiveData.observe(this) { resultState ->
            parseState(resultState, {
                mEmojiList = it
                showInteractionEmojiPopup()
            })
        }
        //直播获取顶部消费列表
        mViewModel.liveConsumeLiveData.observe(this) { (liveId, it) ->
            if (mLiveInfo.liveId == liveId) {
                mBinding.vHeader.updateConsumeList(it)
                mBinding.widgetRoomBanner.upDataMagicLamp()
            }
        }
        //活动滚动信息刷新
        mViewModel.activitiesScrollLiveData.observe(this) {
            mLiveInfo.let { info ->
                mBinding.actMarquee.getActivitiesScroll(mViewModel, info.userId)
            }
        }
        //欢迎语
        mViewModel.welcomeSpeechUpdateData.observe(this) { resultState ->
            parseState(resultState, {
                ToastGravity.showGravity(R.string.modified_successfully)
            }) {
                ToastGravity.showGravity(it.errorMsg)
            }
        }
        //pag下载
        mViewModel.mDownLoadLiveData.observe(this) {
            GlobalDialogManager.showLiveNotice(requireContext(), it)
        }

        //获取游戏列表
        mViewModel.gameLiveData.observe(this) { resultState ->
            parseState(resultState, {
                mBinding.bottom.showGameButton(it.isNotEmpty())
                GameUtils.setLiveCacheGameList(it)
                mViewModel.gameRank(mLiveInfo.liveId)
            })
        }
        //恢复直播间失败
        mViewModel.recoverFailureLiveData.observe(this) {
            onStopLive()
        }
        mViewModel.mSubsidyLiveData.observe(this) { resultState ->
            parseState(resultState, {
                if (mSubsidy == null) {
                    mSubsidy = it
                } else {
                    mSubsidy = it
                    if (it.show) {
                        XPopup.Builder(requireContext())
                            .isDestroyOnDismiss(true)
                            .asCustom(AwardProgressDialog(requireContext(), it))
                            .show()
                    }
                }
            })
        }
        //位置上下锁
        mViewModel.siteLockData.observe(this) { resultState ->
            parseState(resultState, {
                if (it.lock) {
                    ToastGravity.showGravity(R.string.locked_successfully)
                } else {
                    ToastGravity.showGravity(R.string.unlocking_successful)
                }

            }) {
                ToastGravity.showGravity(R.string.operation_failed)
            }
        }
        mViewModel.mBackGiftRedData.observe(this) { resultState ->
            parseState(resultState, {
                mBinding.bottom.setBackPackRed(if (it) View.VISIBLE else View.GONE)
            })
        }
        mViewModel.exitLiveLiveData.observe(this) {
            mRoomFinishCallback?.onRoomFinishCallback()
        }
        TaskRedProxy.observe(this, object : TaskRedListener {
            override fun updateRed(isRed: Boolean) {
                mBinding.bottom.setSettingRed(if (isRed) View.VISIBLE else View.GONE)
            }
        })
        mViewModel.mLampLotteryLiveData.observe(this) { resultState ->
            parseState(resultState, {
                MagicLampWinRewardPopup.show(requireContext(), it)
            }) {
                ToastGravity.showGravity(it.errorMsg)
            }
        }
        mBinding.widgetMagicLamp.openMagicLampCallBack {
            mLiveInfo.userId.let { userId ->
                mViewModel.lampLottery(userId, it.index.toLong())
            }
        }
        //路由监听
        RouterControlManager.observeListener(this) { key, ext ->
            withLoaded {
                when (key) {
                    RouterControlManager.ROUTER_ROOMGAME -> { //打开幸运游戏列表
                        val gameId = ext["gameId"]?.toLongOrNull()
                        if (gameId == null) {
                            showGameList()
                        } else {
                            val gameVo = GameUtils.getLiveCacheGameList()
                                ?.asSequence()
                                ?.flatMap { it.list.asSequence() }
                                ?.find { it.gameID == gameId }
                            if (gameVo != null) {
                                val roomId = mLiveInfo?.userId.toString()
                                GameUtils.showGameFragment(requireContext(), gameVo, roomId = roomId)
                            } else {
                                showGameList()
                            }
                        }
                    }

                    RouterControlManager.ROUTER_GIFT -> { //礼物盘拉起
                        val giftType = ext["giftType"]?.toIntOrNull()
                        mGiftDialogProxy.showGiftPopup(
                            seatList = mBinding.partySeat.getSeatData(),
                            giftType = giftType
                        )
                    }

                    RouterControlManager.ROUTER_UP_MIC -> { //上麦
                        mBinding.partySeat.getNoHavaSeat()?.let { showSitePop(it) }
                    }

                    RouterControlManager.ROUTER_PARTYGAMEUP -> { //上游戏位
                        mGamePlayFragment?.siteUpDown(true)
                        mBaiShunGamePlayFragment?.siteUpDown(true)
                    }
                }
            }
        }
        //更新弹幕信息
        mViewModel.barrageNumberLiveData.observe(this) { resultState ->
            parseState(resultState, {
                mBinding.vEdit.upBarrage(it)
            })
        }
    }

    private fun showGameList() {
        val roomId = (mLiveInfo.userId ?: "").toString()
        GameListPopup.show(requireContext(), GameUtils.getLiveCacheGameList(), roomId)
    }

    /**
     * 显示房间信息
     */
    private fun showRoomInfoPopup() {
        RoomInfoAnchorPopup.show(
            this,
            mLiveInfo.liveId,
            mLiveInfo.userId,
            mLiveInfo.roomId ?: "",
            mLiveInfo.vipLevel,
            mLiveInfo.roomTheme,
            {
                showPartyUserProfilePopup(it, true)
            },
            {
                mBinding.vHeader.updateRoomName(it)
            })
    }

    /**
     * 显示资料卡片
     * search 是否查找座位上的人信息
     */
    private fun showPartyUserProfilePopup(
        userId: Long,
        search: Boolean = false,
        seatBean: SeatBean? = null,
    ) {
        val mutableSeatBean =
            seatBean ?: if (search) mBinding.partySeat.getSeatBeanByUserId(userId) else null
        GlobalPopupManager.showPartyAnchorUserProfilePopup(
            requireContext(), this, mViewModel,
            userId, UserConst.From.LIVE, mLiveInfo.liveId,
            mutableSeatBean, mBanMessageUser,
            onLeaveSeatClickListener = {
                mViewModel.liveSiteDown(mLiveInfo.userId)
            },
            onGiftClickListener = {
                //点击送礼
                mGiftDialogProxy.showGiftPopup(it.toUserBasicVo())
            }, onFollowerClickListener = {

            }, onMessageClickListener = {
                showChatMessage(it.toUserBasicVo())
            }, onSelectMoreCardListener = { infoUser ->
                showSelectMoreCard(infoUser)
            })

    }

    private fun showSelectMoreCard(infoUserResp: InfoOtherResp) {
        val mutableSeatBean = mBinding.partySeat.getSeatBeanByUserId(infoUserResp.userId)
        GlobalPopupManager.showSelectMoreCard(
            requireContext(), this, mViewModel,
            infoUserResp, mutableSeatBean, mBanMessageUser,
            mAdministrators,
            mLiveInfo.liveId,
            mLiveInfo.userId,
            false,
            onInviteOrKickSiteListener = {
                if (it) {
                    mViewModel.partyInviteSite(infoUserResp.userId, null, mLiveInfo.liveId)
                } else {
                    //踢下座位
                    mViewModel.siteKick(infoUserResp.userId, mLiveInfo.userId)
                }
            }, onKickRoomListener = {
                //踢出房间
                mViewModel.kickUser(infoUserResp.userId, mLiveInfo.userId, mLiveInfo.roomId)
            }, onAtClickListener = {
                mBinding.vEdit.atUser(infoUserResp.userId, infoUserResp.nickname)
            }
        )
    }

    /**
     * 显示座位管理
     */
    private fun showSeatPopup(seatBean: SeatBean) {
        XPopup.Builder(requireContext())
            .isViewMode(true)
            .hasShadowBg(true)
            .isDestroyOnDismiss(true)
            .asCustom(
                SeatSettingPopup(
                    requireContext(), seatBean, mViewModel, UserManager.getUserId(), mLiveInfo.liveId
                ) {
                    showSitePop(seatBean)
                }
            )
            .show()
    }

    /**
     * 上麦
     */
    private fun showSitePop(seatBean: SeatBean) {
        //麦位被锁不响应
        if (seatBean.siteLock != true) {
            StartLiveProxy.permissionAudio(requireContext(), {
                upSeat(false, seatBean.seatId)
            })
        }
    }

    private fun upSeat(isInvite: Boolean, seatId: Int?) {
        StartLiveProxy.permissionAudio(requireContext(), {
            mViewModel.liveSiteUp(mLiveInfo.userId, isInvite, seatId)
        })
    }

    /**
     * 显示Emoji管理
     */
    private fun showInteractionEmojiPopup() {
        if (mEmojiList == null) {
            mViewModel.emojiList()
            return
        }
        mEmojiList?.let {
            XPopupUtils.showViewPopup(
                InteractionEmojiPopup(requireContext(), it, mViewModel, {
                    mViewModel.sendEmoji(it.id, mLiveInfo.liveId)
                }) {
                    mEmojiList = null
                }
            )
        }
    }

    /**
     * 显示解锁座位弹窗
     */
    private fun showUnLockSeatPopup(seatId: Int) {
        XPopup.Builder(requireContext())
            .isViewMode(true)
            .hasShadowBg(false)
            .moveUpToKeyboard(false)
            .isDestroyOnDismiss(true)
            .asCustom(UnLockSeatPopup(requireContext()) {
                mViewModel.siteLock(seatId, false, mLiveInfo.userId)
            })
            .show()
    }

    /**
     * 显示房间管理RoomManagement
     */
    private fun showRoomManagementPopup() {
        XPopup.Builder(requireContext())
            .isViewMode(true)
            .hasShadowBg(false)
            .moveUpToKeyboard(false)
            .isDestroyOnDismiss(true)
            .asCustom(
                RoomManagementPopup(requireContext(), true,
                    1,
                    true,
                    false,
                    mLiveInfo,
                    mViewModel, mBinding.widgetGift.getIsOpenGift(), mBinding.widgetGift.getIsOpenSound(),
                    onKeyboardStateListener = {
                        mBinding.vEdit.setKeyboardListerState(it)
                    }, onCloseBack = {
                        if (!GameUtils.gameRun && !mGameMode) {
                            onStopLive(false)
                        } else {
                            ToastGravity.showGravity(R.string.exit_party_paly_game_tips)
                        }
                    }, onOpenGiftAnimation = {
                        mBinding.widgetGift.setIsOpenGiftAnimation(it)
                        mBinding.widgetMagicLamp.setIsOpenGiftAnimation(it)
                    }, onOpenGiftSound = {
                        mBinding.widgetGift.setIsOpenSound(it)
                    }, music = {
                        MusicPopup.show(this@PartyGameAnchorFragment) {
                            upSeat(false, null)
                        }
                    }, onExitTherRoom = {
                        if (GameUtils.gameRun || mGameMode) {
                            ToastGravity.showGravity(R.string.exit_party_paly_game_tips)
                            return@RoomManagementPopup
                        }
                        exitRoom()
                    }, onUserClick = {
                        showPartyUserProfilePopup(it, true)
                    }, onInvitationFriend = {
                        val fragmentManager = childFragmentManager
                        RoomInvitationFragmentDialog().apply {
                            arguments = bundleOf("liveId" to mLiveInfo.liveId)
                        }.show(
                            fragmentManager,
                            "RoomInvitationFragmentDialog"
                        )

                    })
            )
            .show()
    }

    override fun onNetwork(isNetwork: Boolean, isConnected: Boolean) {
        if (mPauseLiving) {
            return
        }
        withLoaded {
            //如果上次是断开连接，这次连接上了，需要重连
            if (isConnected) {
                onRecoverLive()
            }
        }
    }

    /**
     * 调用重连
     */
    private fun onRecoverLive() {
        withLoaded {
            mViewModel.recoverLive(mLiveInfo.roomId)
        }
    }

    /**
     * 退出直播间
     */
    private fun exitRoom() {
        mViewModel.exitLive(mLiveInfo.userId, mLiveInfo.roomId)
    }

    fun setOnRoomFinishCallback(l: OnRoomFinishCallback) {
        mRoomFinishCallback = l
    }

    //停止直播
    private fun onStopLive(needLoading: Boolean = false) {
        if (mStopLive) {
            return
        }
        mViewModel.stopLive(mLiveInfo.liveId, needLoading, mLiveInfo.roomId)
        mStopLive = true
    }

    //重置直播间UI
    private fun resetLive() {
        mBinding.vEdit.reset()
    }

    override fun onBackPressed(): Boolean {
        if (!isCreated() || activity?.isFinishing != false) {
            return true
        }
        if (GameUtils.gameRun || mGameMode) {
            ToastGravity.showGravity(R.string.exit_party_paly_game_tips)
            return true
        }
        LiveHangUpDialog.showDialog(
            requireContext(),
            null,
            mLiveInfo,
            null,
            true
        ) {
            exitRoom()
        }
        return true
    }

    override fun onDestroyView() {
        resetLive()
        mBinding.partySeat.destroyView()
        LiveEngineManage.getGameEngineHandler()?.unloadGame()
        GameUtils.removeGameStateListener(this)
        mViewModel.stopClearTimeJob()
        mViewModel.cancelGameRankJob()
        super.onDestroyView()
    }

    /**
     * 展示消息列表
     */
    private fun showChatMessage(userBase: UserBasicVo? = null) {
        if (userBase != null) {
            childFragmentManager.showNewDialogFragment(
                MessageSingleDialogFragment(
                    userBase.userId,
                    userBase.avatar,
                    userBase.avatarFrame,
                    userBase.chatBubble,
                    nestedPage = false,
                    singlePage = true,
                    needClickAvatar = false
                ), MessageSessionFragment.FRAGMENT_TAG
            )
        } else {
            mSessionFragment.show(
                childFragmentManager,
                MessageSessionDialogFragment.FRAGMENT_TAG
            )
        }
    }

    override fun setMessageHeight(h: Int) {
        mBinding.vMessage.setMessageHeight(h)
    }

    /**
     * 游戏回调
     */
    override fun gamePlayerStart() {
        PartyUserStateUtil.inTheGame = true
        ViewUtils.setMargin(mBinding.llGift, 0, 0, 0, 100.dp)
        mBinding.widgetGift.visibility = View.GONE
        mGameMode = true
    }

    override fun gamePlayerStop() {
        PartyUserStateUtil.inTheGame = false
        mBinding.widgetGift.visibility = View.VISIBLE
        ViewUtils.setMargin(mBinding.llGift, 0, 0, 0, 12.dp)
        mGameMode = false
        if (mLiveIsClose) {
            mLiveStopReceiptResp?.let {
                Router.builder(RoutePath.VOICE_END_ACTIVITY)
                    .withAny(LiveConst.Params.LIVE_END_INFO, it)
                    .withInt("liveType", LiveConst.Type.PARTY_GAME_LIVE)
                    .navigation(requireActivity())
            }
            mRoomFinishCallback?.onRoomFinishCallback()
        }
    }

    override fun gamePlayerInSeat(inSeat: Boolean) {
        PartyUserStateUtil.inTheGameSeat = inSeat
    }

    override fun gameSeatClick(userId: Long) {
        showPartyUserProfilePopup(userId, false)
    }

    override fun gameStart() {
    }

    override fun gameClose() {
        if (mLiveIsClose) {
            mLiveStopReceiptResp?.let {
                Router.builder(RoutePath.VOICE_END_ACTIVITY)
                    .withAny(LiveConst.Params.LIVE_END_INFO, it)
                    .withInt("liveType", LiveConst.Type.PARTY_GAME_LIVE)
                    .navigation(requireActivity())
            }
            mRoomFinishCallback?.onRoomFinishCallback()
        }
    }

    /**
     * 更新禁止发言用户
     */
    private fun upDataBanMessage(liveInfo: LiveRoomInfo) {
        mBanMessageUser.clear()
        liveInfo.banMessageUser?.let { banMessageUserJson ->
            val data: List<Long>? = JsonUtils.fromJson(banMessageUserJson)
            data?.let {
                mBanMessageUser.addAll(it)
            }
        }
    }

    /**
     * 更新管理员
     */
    private fun upDataAdministrator(liveInfo: LiveRoomInfo) {
        mAdministrators.clear()
        liveInfo.administrator?.let {
            val data: List<Long>? = JsonUtils.fromJson(it)
            if (data?.isNotEmpty() != null) {
                mBinding.partySeat.upDataUserPosition(data, mLiveInfo.userId)
                mAdministrators.addAll(data)
            }
        }
    }

    /**
     * 更新皮肤
     */
    private fun setSkinUi() {
        val themeData = AppConfigManager.getUserTheme(mLiveInfo.roomTheme)
        mBinding.partySeat.setTheme(themeData)
        mBinding.vHeader.setTheme(themeData)
        mBinding.bottom.setTheme(themeData)
    }

    companion object {

        private const val pageType = LiveConst.Page.LIVE_ANCHOR
    }

}